﻿package frEngine.animateControler.skilEffect
{
    import __AS3__.vec.*;
    import baseEngine.core.*;
    import flash.events.*;
    import flash.geom.*;
    import frEngine.*;
    import frEngine.animateControler.*;
    import frEngine.animateControler.keyframe.*;
    import frEngine.core.*;
    import frEngine.event.*;
    import frEngine.shader.filters.*;
    import frEngine.shader.filters.vertexFilters.*;
    import frEngine.shader.registType.*;

    public class SwordLightControler_Normal extends MeshAnimateBase
    {
        private var start1:Vector3D;
        private var end1:Vector3D;
        private var start2:Vector3D;
        private var end2:Vector3D;
        private var _upVector:Vector3D;
        private var _tempVector:Vector3D;
        private var _templeMatrix3d:Matrix3D;
        private var _curPos:Vector3D;
        private var _totalLen:uint = 1;
        private var _zero:Vector3D;
        public var useTwoLine:Boolean = false;
        public var splitBlankKeyNum:int = 3;
        private var perFrameFragment:int = 8;
        private var totalLineNum:int = 0;
        private var posList:Vector.<Number>;
        private var rotList:Vector.<Number>;
        private var swordVertexFilter:SwordLightVertexFilter_Normal;
        private var enabledShut:Number = 1;
        private var _maxLen:uint = 0;
        private var _hasLineControler:Boolean;
        private var _length1:int;
        private var _length2:int;
        private var _angle:Number;
        private var _splitBlankKeyNum:int;
        private var _perFrameFragment:int;
        private var _preFrame:int = -1;

        public function SwordLightControler_Normal()
        {
            this._upVector = new Vector3D();
            this._tempVector = new Vector3D();
            this._templeMatrix3d = new Matrix3D();
            this._curPos = new Vector3D();
            this._zero = new Vector3D();
            this.posList = new Vector.<Number>;
            this.rotList = new Vector.<Number>;
            this.swordVertexFilter = new SwordLightVertexFilter_Normal((this.splitBlankKeyNum + 1));
            return;
        }// end function

        public function set hasLineControler(param1:Boolean) : void
        {
            if (this._hasLineControler == param1)
            {
                return;
            }
            this._hasLineControler = param1;
            if (this.totalLineNum > 0)
            {
                this.reInit();
            }
            return;
        }// end function

        public function initData(param1:int, param2:int, param3:Number, param4:int, param5:int) : void
        {
            this._length1 = param1;
            this._length2 = param2;
            this._angle = param3;
            this._splitBlankKeyNum = param4;
            this._perFrameFragment = param5;
            this.reInit();
            return;
        }// end function

        private function reInit() : void
        {
            var _loc_2:Number = NaN;
            var _loc_3:Number = NaN;
            if (this._hasLineControler)
            {
                this.start1 = new Vector3D((-this._length1) / 2, 0, 0);
                this.end1 = new Vector3D(this._length1 / 2, 0, 0);
            }
            else
            {
                this.start1 = new Vector3D(0, (-this._length1) / 2, 0);
                this.end1 = new Vector3D(0, this._length1 / 2, 0);
            }
            this.useTwoLine = this._length2 > 1 ? (true) : (false);
            if (this.useTwoLine)
            {
                if (this._hasLineControler)
                {
                    _loc_2 = Math.cos(this._angle) * this._length2 / 2;
                    _loc_3 = Math.sin(this._angle) * this._length2 / 2;
                    this.start2 = new Vector3D(_loc_2, 0, _loc_3);
                    this.end2 = new Vector3D(-_loc_2, 0, -_loc_3);
                }
                else
                {
                    this.start2 = new Vector3D((-this._length2) / 2, 0, 0);
                    this.end2 = new Vector3D(this._length2 / 2, 0, 0);
                }
            }
            this.splitBlankKeyNum = this._splitBlankKeyNum > 50 ? (50) : (this._splitBlankKeyNum);
            this.perFrameFragment = this._perFrameFragment > 15 ? (15) : (this._perFrameFragment);
            this.totalLineNum = this.splitBlankKeyNum * this.perFrameFragment + 1;
            this.createCIndexBuffer();
            this.createTriangleIndex();
            this.createUV();
            this.createTime();
            this.createPostion();
            var _loc_1:* = this.splitBlankKeyNum + 1;
            if (this.swordVertexFilter.reInit(_loc_1))
            {
                targetMesh.material.materialParams.needRebuild = true;
            }
            this.setPlayLable(this.defaultLable);
            this._maxLen = _loc_1 * 4;
            return;
        }// end function

        override public function get defaultLable() : Label3D
        {
            var _loc_1:* = new Label3D(0, int.MAX_VALUE, "#default#", 0);
            _defaultLable = new Label3D(0, int.MAX_VALUE, "#default#", 0);
            return _defaultLable;
        }// end function

        override protected function getBaseValue(param1:Pivot3D) : Object
        {
            return this.enabledShut;
        }// end function

        override protected function setTargetProperty(param1) : void
        {
            this.enabledShut = Number(param1);
            return;
        }// end function

        override protected function calculateFrameValue(param1:int) : void
        {
            var _loc_2:* = getTimeIndex(param1, _keyframes);
            var _loc_3:* = _keyframes[_loc_2];
            _cache[param1] = _loc_3.value;
            return;
        }// end function

        override protected function setSurfaceHander(event:Event) : void
        {
            super.setSurfaceHander(event);
            FrEventDispatcher.instance.proxyAddEventListener(targetMesh.material, Engine3dEventName.MATERIAL_REBUILDER, this.getRegsiterHander);
            targetMesh.material.materialParams.setVertexFilter(this.swordVertexFilter);
            return;
        }// end function

        private function getRegsiterHander(event:Event) : void
        {
            var _loc_3:VcParam = null;
            var _loc_2:* = targetMesh.material.getParam("{keyLinePos}", true);
            if (_loc_2)
            {
                _loc_2.value = this.posList;
                _loc_3 = targetMesh.material.getParam("{keyLineRot}", true);
                _loc_3.value = this.rotList;
            }
            return;
        }// end function

        private function createUV() : void
        {
            var _loc_6:Number = NaN;
            var _loc_7:int = 0;
            var _loc_8:Number = NaN;
            var _loc_1:* = new Vector.<Number>;
            var _loc_2:* = 1 / this.splitBlankKeyNum;
            var _loc_3:* = _loc_2 / this.perFrameFragment;
            var _loc_4:int = 0;
            while (_loc_4 < this.splitBlankKeyNum)
            {
                
                _loc_6 = _loc_4 * _loc_2;
                _loc_7 = 0;
                while (_loc_7 < this.perFrameFragment)
                {
                    
                    _loc_8 = 1 - (_loc_6 + _loc_7 * _loc_3);
                    _loc_1.push(_loc_8, 1);
                    _loc_1.push(_loc_8, 0);
                    if (this.useTwoLine)
                    {
                        _loc_1.push(_loc_8, 1);
                        _loc_1.push(_loc_8, 0);
                    }
                    _loc_7++;
                }
                _loc_4++;
            }
            _loc_1.push(0, 1);
            _loc_1.push(0, 0);
            if (this.useTwoLine)
            {
                _loc_1.push(0, 1);
                _loc_1.push(0, 0);
            }
            var _loc_5:* = targetSurface.getVertexBufferByNameId(FilterName_ID.UV_ID);
            _loc_5.vertexVector = _loc_1;
            _loc_5.toUpdate();
            return;
        }// end function

        private function createCIndexBuffer() : void
        {
            var _loc_5:int = 0;
            var _loc_6:int = 0;
            var _loc_7:int = 0;
            var _loc_8:int = 0;
            var _loc_9:int = 0;
            var _loc_1:* = new Vector.<Number>;
            var _loc_2:* = this.useTwoLine ? (4) : (2);
            var _loc_3:int = 0;
            while (_loc_3 < this.splitBlankKeyNum)
            {
                
                _loc_5 = _loc_3 - 1;
                var _loc_10:int = 0;
                _loc_5 = 0;
                _loc_6 = _loc_3 + 1;
                _loc_7 = _loc_6 + 1;
                var _loc_10:* = this.splitBlankKeyNum;
                _loc_7 = this.splitBlankKeyNum;
                _loc_8 = 0;
                while (_loc_8 < this.perFrameFragment)
                {
                    
                    _loc_9 = 0;
                    while (_loc_9 < _loc_2)
                    {
                        
                        _loc_1.push(_loc_3, _loc_5, _loc_6, _loc_7);
                        _loc_9++;
                    }
                    _loc_8++;
                }
                _loc_3++;
            }
            _loc_9 = 0;
            while (_loc_9 < _loc_2)
            {
                
                _loc_1.push(this.splitBlankKeyNum, this.splitBlankKeyNum, this.splitBlankKeyNum, this.splitBlankKeyNum);
                _loc_9++;
            }
            var _loc_4:* = targetSurface.getVertexBufferByNameId(FilterName_ID.SKIN_INDICES_ID);
            _loc_4.vertexVector = _loc_1;
            _loc_4.toUpdate();
            return;
        }// end function

        private function createPostion() : void
        {
            var _loc_5:int = 0;
            var _loc_6:Number = NaN;
            var _loc_1:* = 1 / this.perFrameFragment;
            var _loc_2:* = new Vector.<Number>;
            var _loc_3:int = 0;
            while (_loc_3 < this.splitBlankKeyNum)
            {
                
                _loc_5 = 0;
                while (_loc_5 < this.perFrameFragment)
                {
                    
                    _loc_6 = _loc_5 * _loc_1;
                    _loc_2.push(this.start1.x, this.start1.y, this.start1.z, _loc_6);
                    _loc_2.push(this.end1.x, this.end1.y, this.end1.z, _loc_6);
                    if (this.useTwoLine)
                    {
                        _loc_2.push(this.start2.x, this.start2.y, this.start2.z, _loc_6);
                        _loc_2.push(this.end2.x, this.end2.y, this.end2.z, _loc_6);
                    }
                    _loc_5++;
                }
                _loc_3++;
            }
            _loc_2.push(this.start1.x, this.start1.y, this.start1.z, 1);
            _loc_2.push(this.end1.x, this.end1.y, this.end1.z, 1);
            if (this.useTwoLine)
            {
                _loc_2.push(this.start2.x, this.start2.y, this.start2.z, 1);
                _loc_2.push(this.end2.x, this.end2.y, this.end2.z, 1);
            }
            var _loc_4:* = targetSurface.getVertexBufferByNameId(FilterName_ID.POSITION_ID);
            _loc_4.vertexVector = _loc_2;
            _loc_4.toUpdate();
            return;
        }// end function

        private function createTime() : void
        {
            var _loc_5:int = 0;
            var _loc_6:Number = NaN;
            var _loc_7:Number = NaN;
            var _loc_8:Number = NaN;
            var _loc_9:Number = NaN;
            var _loc_10:Number = NaN;
            var _loc_11:Number = NaN;
            var _loc_1:* = 1 / this.perFrameFragment;
            var _loc_2:* = new Vector.<Number>;
            var _loc_3:int = 0;
            while (_loc_3 < this.splitBlankKeyNum)
            {
                
                _loc_5 = 0;
                while (_loc_5 < this.perFrameFragment)
                {
                    
                    _loc_6 = _loc_5 * _loc_1;
                    _loc_7 = 1 - _loc_6;
                    _loc_8 = _loc_7 * _loc_7 * _loc_7;
                    _loc_9 = 3 * _loc_6 * _loc_7 * _loc_7;
                    _loc_10 = 3 * _loc_6 * _loc_6 * _loc_7;
                    _loc_11 = _loc_6 * _loc_6 * _loc_6;
                    _loc_2.push(_loc_8, _loc_9, _loc_10, _loc_11);
                    _loc_2.push(_loc_8, _loc_9, _loc_10, _loc_11);
                    if (this.useTwoLine)
                    {
                        _loc_2.push(_loc_8, _loc_9, _loc_10, _loc_11);
                        _loc_2.push(_loc_8, _loc_9, _loc_10, _loc_11);
                    }
                    _loc_5++;
                }
                _loc_3++;
            }
            _loc_2.push(0, 0, 0, 1);
            _loc_2.push(0, 0, 0, 1);
            if (this.useTwoLine)
            {
                _loc_2.push(0, 0, 0, 1);
                _loc_2.push(0, 0, 0, 1);
            }
            var _loc_4:* = targetSurface.getVertexBufferByNameId(FilterName_ID.PARAM0_ID);
            _loc_4.vertexVector = _loc_2;
            _loc_4.toUpdate();
            return;
        }// end function

        private function createTriangleIndex() : void
        {
            var _loc_3:int = 0;
            var _loc_4:int = 0;
            var _loc_1:* = this.totalLineNum - 1;
            var _loc_2:* = new Vector.<uint>;
            if (this.useTwoLine)
            {
                _loc_3 = 0;
                while (_loc_3 < _loc_1)
                {
                    
                    _loc_4 = _loc_3 * 4;
                    _loc_2.push(_loc_4);
                    _loc_2.push((_loc_4 + 1));
                    _loc_2.push(_loc_4 + 4);
                    _loc_2.push((_loc_4 + 1));
                    _loc_2.push(_loc_4 + 5);
                    _loc_2.push(_loc_4 + 4);
                    _loc_2.push(_loc_4 + 2);
                    _loc_2.push(_loc_4 + 3);
                    _loc_2.push(_loc_4 + 6);
                    _loc_2.push(_loc_4 + 3);
                    _loc_2.push(_loc_4 + 7);
                    _loc_2.push(_loc_4 + 6);
                    _loc_3++;
                }
            }
            else
            {
                _loc_3 = 0;
                while (_loc_3 < _loc_1)
                {
                    
                    _loc_4 = _loc_3 * 2;
                    _loc_2.push(_loc_4);
                    _loc_2.push((_loc_4 + 1));
                    _loc_2.push(_loc_4 + 2);
                    _loc_2.push((_loc_4 + 1));
                    _loc_2.push(_loc_4 + 3);
                    _loc_2.push(_loc_4 + 2);
                    _loc_3++;
                }
            }
            targetSurface.indexBufferFr.indexVector = _loc_2;
            targetSurface.indexBufferFr.numTriangles = _loc_2.length / 3;
            targetSurface.indexBufferFr.toUpdate();
            return;
        }// end function

        override public function set targetObject3d(param1:Pivot3D) : void
        {
            if (targetObject3d)
            {
                FrEventDispatcher.instance.proxyRemoveEventListener(targetObject3d, Engine3dEventName.VISIBLE_CHANGE_EVENT, this.visibleChangeHander);
            }
            if (param1)
            {
                FrEventDispatcher.instance.proxyAddEventListener(param1, Engine3dEventName.VISIBLE_CHANGE_EVENT, this.visibleChangeHander);
            }
            super.targetObject3d = param1;
            return;
        }// end function

        private function visibleChangeHander(event:Event) : void
        {
            this.posList.length = 0;
            this.rotList.length = 0;
            return;
        }// end function

        override public function toUpdateAnimate(param1:Boolean = false) : void
        {
            var _loc_4:Vector3D = null;
            var _loc_6:Vector3D = null;
            var _loc_7:Vector3D = null;
            var _loc_2:* = targetMesh.timerContorler.curFrame;
            if (this._preFrame == _loc_2)
            {
                return;
            }
            if (this._preFrame > _loc_2 || _loc_2 == 1)
            {
                this.posList.length = 0;
                this.rotList.length = 0;
            }
            this._preFrame = _loc_2;
            if (this.posList.length == 0)
            {
                this.resetLine1();
            }
            var _loc_3:* = targetMesh.world.transformVector(this._zero);
            if (this._hasLineControler)
            {
                _loc_6 = this._tempVector;
                _loc_6 = _loc_3.subtract(this._curPos);
                _loc_6.normalize();
                this._upVector = _loc_6.equals(Vector3D.Y_AXIS) ? (Vector3D.Z_AXIS) : (Vector3D.Y_AXIS);
                _loc_7 = this._upVector.crossProduct(_loc_6);
                _loc_7.normalize();
                this._upVector = _loc_6.crossProduct(_loc_7);
                var _loc_8:int = 0;
                _loc_6.w = 0;
                var _loc_8:* = _loc_8;
                this._upVector.w = _loc_8;
                _loc_7.w = _loc_8;
                this._templeMatrix3d.copyColumnFrom(0, _loc_7);
                this._templeMatrix3d.copyColumnFrom(1, _loc_6);
                this._templeMatrix3d.copyColumnFrom(2, this._upVector);
                _loc_4 = this._templeMatrix3d.decompose(Orientation3D.QUATERNION)[1];
            }
            else
            {
                _loc_4 = targetMesh.world.decompose(Orientation3D.QUATERNION)[1];
            }
            var _loc_5:* = _loc_3.equals(this._curPos) ? (0) : (1);
            this._curPos = _loc_3;
            this.rotList.unshift(_loc_4.x, _loc_4.y, _loc_4.z, _loc_4.w);
            this.posList.unshift(this._curPos.x, this._curPos.y, this._curPos.z, _loc_5);
            var _loc_8:* = this._maxLen;
            this.posList.length = this._maxLen;
            this.rotList.length = _loc_8;
            return;
        }// end function

        private function resetLine1() : void
        {
            var _loc_1:* = this.splitBlankKeyNum + 1;
            var _loc_2:* = targetMesh.world;
            this._curPos = _loc_2.transformVector(this._zero);
            var _loc_3:* = this._curPos.x;
            var _loc_4:* = this._curPos.y;
            var _loc_5:* = this._curPos.z;
            var _loc_6:int = 0;
            while (_loc_6 < _loc_1)
            {
                
                this.posList.push(0, 0, 0, 0);
                this.rotList.push(0, 0, 0, 1);
                _loc_6++;
            }
            this._totalLen = 1;
            return;
        }// end function

        override public function get type() : int
        {
            return AnimateControlerType.swordLight_Normal;
        }// end function

    }
}
